﻿/**************************************************
 *  Author :    youping
 *  CreateDate: 2021-06-19
 *  Title:      平台文件发布： 文件复制功能
**************************************************/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Configuration;
using System.Threading;

namespace Demo.FolderOp
{
    public partial class FileCopy : Form
    {
        public FileCopy()
        {
            InitializeComponent();
            InitPage();
        }

        //创建一个委托，是为访问TextBox控件服务的。
        public delegate void CopyTxt(string url, DataTable myDt, FileMethod.DelegateProgressBar myProgressBar);
        //定义一个委托变量
        public CopyTxt copyTxt;

        //此为在非创建线程中的调用方法，其实是使用FileCopy的Invoke方法。
        public void ThreadMethodTxt(string url, DataTable myDt, FileMethod.DelegateProgressBar myProgressBar)
        {
            IAsyncResult result = this.BeginInvoke(copyTxt, url, myDt, myProgressBar);
            //this.EndInvoke(result);
        }

        public void CopyFileMethod(string url, DataTable myDt, FileMethod.DelegateProgressBar myProgressBar)
        {
            bool IsRight = true;
            DateTime tempStartTime = DateTime.Now;
            foreach (DataRow myDr in myDt.Rows)
            {
                ////处理复制粘贴
                if (FileMethod.DocumentCopyToTargetLocation(this.txtWhereFloderUrl.Text, myDr["Url"].ToString(), myProgressBar))
                {
                }
                else
                {
                    IsRight = false;

                }
                if (!IsRight)
                {
                    CommonForm.ShowMessage("复制失败，" + CommonMethod.ImportTip(tempStartTime, DateTime.Now), 2);
                    break;
                }
            }

            if (IsRight)
            {
                CommonForm.ShowMessage("复制成功，" + CommonMethod.ImportTip(tempStartTime, DateTime.Now));

                //删除源文件文件夹
                this.btnDelSourseFolder_Click(null, null);
            }
        }

        private void InitPage()
        {
            //隐藏读取配置按钮
            //this.btnGetConfig.Hide();
            //隐藏目标配置地址
            this.txtTargetFloderUrl.Hide();
            //隐藏选择文件夹按钮
            this.btnSelectTargertFloder.Hide();
            this.btnConfirmCopy.Hide();

            this.chkIsDelSourseFolder.Checked = true;
            //加载配置
            btnGetConfig_Click(null, null);

            //实例化委托
            copyTxt = new CopyTxt(CopyFileMethod);

        }

        /// <summary>
        /// 选择需要复制的文件路径
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSelectFloder_Click(object sender, EventArgs e)
        {
            DialogResult dr = this.whereFolderBrowserDialog.ShowDialog();
            if (dr == System.Windows.Forms.DialogResult.OK)
            {
                this.txtWhereFloderUrl.Text = whereFolderBrowserDialog.SelectedPath;
            }
        }

        /// <summary>
        /// 选择目标路径，复制到哪里
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSelectTargertFloder_Click(object sender, EventArgs e)
        {
            DialogResult dr = this.targetFolderBrowserDialog.ShowDialog();
            if (dr == System.Windows.Forms.DialogResult.OK)
            {
                this.txtTargetFloderUrl.Text = this.targetFolderBrowserDialog.SelectedPath;
            }
        }

        #region 验证文件路径是否已经选择
        /// <summary>
        /// 验证文件路径是否已经选择
        /// </summary>
        /// <returns></returns>
        private bool CheckInput()
        {
            //验证
            if (!string.IsNullOrWhiteSpace(this.txtWhereFloderUrl.Text))
            {
                //判断文件夹路径是否存在
                if (!Directory.Exists(this.txtWhereFloderUrl.Text))
                {
                    CommonForm.ShowMessage("文件夹路径不存在，请检查！", 1);
                    return false;
                }

                //验证文件夹内是否存在具体文件
                string[] myFiles = Directory.GetFiles(".");
                if (myFiles.Length == 0)
                {
                    CommonForm.ShowMessage("文件夹为空，请检查！", 1);
                    return false;
                }
            }
            else
            {
                CommonForm.ShowMessage("请选择文件路径！", 1);
                return false;
            }

            //判断目标文件夹是否存在
            if (!string.IsNullOrWhiteSpace(this.txtTargetFloderUrl.Text))
            {
                //判断文件夹路径是否存在
                if (!Directory.Exists(this.txtTargetFloderUrl.Text))
                {
                    CommonForm.ShowMessage("目标文件夹路径不存在，请检查！", 1);
                    return false;
                }
            }
            else
            {
                CommonForm.ShowMessage("请选择目标文件夹路径！", 1);
                return false;
            }
            return true;
        }

        private bool CheckInputV2()
        {
            //验证
            if (!string.IsNullOrWhiteSpace(this.txtWhereFloderUrl.Text))
            {
                //判断文件夹路径是否存在
                if (!Directory.Exists(this.txtWhereFloderUrl.Text))
                {
                    CommonForm.ShowMessage("文件夹路径不存在，请检查！", 1);
                    return false;
                }

                //验证文件夹内是否存在具体文件
                string[] myFiles = Directory.GetFiles(".");
                if (myFiles.Length == 0)
                {
                    CommonForm.ShowMessage("文件夹为空，请检查！", 1);
                    return false;
                }
            }
            else
            {
                CommonForm.ShowMessage("请选择文件路径！", 1);
                return false;
            }

            DataTable myDt = (DataTable)this.dgvUrl.DataSource;
            string temp = string.Empty;
            foreach (DataRow myDr in myDt.Rows)
            {
                //判断目标文件夹是否存在
                temp = myDr["Url"].ToString();
                if (!string.IsNullOrWhiteSpace(temp))
                {
                    //判断文件夹路径是否存在
                    if (!Directory.Exists(temp))
                    {
                        CommonForm.ShowMessage(myDr["Index"].ToString() + "目标文件夹路径" + temp + "不存在，请检查！", 1);
                        return false;
                    }
                }
                else
                {
                    CommonForm.ShowMessage("请选择目标文件夹路径！", 1);
                    return false;
                }
            }
            return true;
        }
        #endregion

        /// <summary>
        /// 复制文件到对应的目录中
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnConfirmCopy_Click(object sender, EventArgs e)
        {
            if (!this.CheckInput())
            {
                return;
            }

            //委托
            FileMethod.DelegateProgressBar myProgressBar = new FileMethod.DelegateProgressBar(SetProgressBar);
            //ProgressBarPro myProgressBar = SetProgressBar;

            //处理复制粘贴
            if (FileMethod.DocumentCopyToTargetLocation(this.txtWhereFloderUrl.Text, this.txtTargetFloderUrl.Text, myProgressBar))
            {
                CommonForm.ShowMessage("复制成功");
            }
            else
            {
                CommonForm.ShowMessage("复制失败", 2);
            }
        }

        //读取配置，将配置展示到界面显示
        private void btnGetConfig_Click(object sender, EventArgs e)
        {
            Configuration myConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
            string[] myKeys = myConfig.AppSettings.Settings.AllKeys;
            DataTable myDt = new DataTable();
            if (!myDt.Columns.Contains("Index"))
            {
                myDt.Columns.AddRange(new DataColumn[] {
                new DataColumn("Index", typeof(string)),
                new DataColumn("Url", typeof(string))
                });
            }

            DataRow myNewDr = null;
            int i = 0;
            foreach (string key in myKeys)
            {
                if (key == "SourseUrl")
                {
                    this.txtWhereFloderUrl.Text = ConfigurationManager.AppSettings["SourseUrl"];
                }
                else if (key.IndexOf("TargetUrl") >= 0)
                {
                    //this.txtTargetFloderUrl.Text = ConfigurationManager.AppSettings[key];
                    myNewDr = myDt.NewRow();
                    myNewDr["Index"] = ++i;
                    //赋值配置的地址
                    myNewDr["Url"] = ConfigurationManager.AppSettings[key];
                    myDt.Rows.Add(myNewDr);
                    myDt.AcceptChanges();
                }
            }
            if (myDt != null)
            {
                //设置列头居中
                this.dgvUrl.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
                this.dgvUrl.DataSource = myDt;
                this.dgvUrl.Columns[0].HeaderCell.Value = "序号";
                this.dgvUrl.Columns[0].ReadOnly = true;
                //this.dgvUrl.Columns[1].HeaderCell.Style = "text-align: center;";
                this.dgvUrl.Columns[1].HeaderCell.Value = "目标路径地址";
                this.dgvUrl.Columns[1].Width = 200;

                //DataGridViewButtonColumn myButton = new DataGridViewButtonColumn();
                //myButton.HeaderCell.Value = "选择路径";
                //if (!this.dgvUrl.Columns.Contains(myButton))
                //{
                //    this.dgvUrl.Columns.Add(myButton);
                //}
                //this.dgvUrl.Sort();
            }
        }

        #region 检查源待复制的配置是否正确
        private ReturnModel CheckConfigIsRight()
        {
            ReturnModel myReturnModel = new ReturnModel() { success = true };
            try
            {
                //检查待复制的地址文件夹是否存在
                if (!Directory.Exists(this.txtWhereFloderUrl.Text.Trim()))
                {
                    myReturnModel.success = false;
                    myReturnModel.message = this.txtWhereFloderUrl.Text.Trim() + "路径不存在，请检查！";
                    return myReturnModel;
                }
                else if (!FileMethod.CheckFolderFileExists(this.txtWhereFloderUrl.Text.Trim()))
                {
                    //判断是否存在文件
                    myReturnModel.success = false;
                    myReturnModel.message = this.txtWhereFloderUrl.Text.Trim() + "路径下不存在文件，请检查！";
                    return myReturnModel;
                }
            }
            catch (Exception myEx)
            {
                throw myEx;
            }
            return myReturnModel;
        }
        #endregion

        #region 获取配置datatable 的 url 和 检查路径地址是否正确  CheckConfigIsRight
        private ReturnModel GetDataGridViewUrl(List<string> myUrlList)
        {
            try
            {
                ReturnModel myReturnModel = new ReturnModel() { success = true };

                DataTable myDt = (DataTable)this.dgvUrl.DataSource;
                string tempUrl = string.Empty;

                foreach (DataRow myDr in myDt.Rows)
                {
                    tempUrl = myDr["Url"].ToString();

                    //判断路径是否存在
                    if (Directory.Exists(tempUrl))
                    {
                        CommonMethod.ListAdd(myUrlList, tempUrl);
                    }
                    else
                    {
                        myReturnModel.success = false;
                        myReturnModel.message = tempUrl + "路径不存在，请重新选择地址！";
                        break;
                    }
                }
                if (!myReturnModel.success)
                {
                    return myReturnModel;
                }
                else if (myUrlList.Count == 0)
                {
                    myReturnModel.success = false;
                    myReturnModel.message = "路径地址为空，请输入后保存！";
                    return myReturnModel;
                }
                return myReturnModel;
            }
            catch (Exception myEx)
            {
                throw myEx;
            }
        }
        #endregion

        //保存配置路径地址
        private void btnSaveConfig_Click(object sender, EventArgs e)
        {
            try
            {
                //检查待复制文件夹情况
                ReturnModel result = this.CheckConfigIsRight();
                if (!result.success)
                {
                    CommonForm.ShowMessage(result.message, 1);
                    return;
                }

                //检查复制目标配置情况
                List<string> myUrlList = new List<string>();
                result = this.GetDataGridViewUrl(myUrlList);
                if (!result.success)
                {
                    CommonForm.ShowMessage(result.message, 1);
                    return;
                }

                Configuration myConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
                string[] myKeys = myConfig.AppSettings.Settings.AllKeys;

                //开始操作Config文件，将config按照类的方式打开
                Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                //1. 保存待复制文件路径地址
                if (myKeys.Contains("SourseUrl"))
                {
                    //保存要复制的路径地址
                    config.AppSettings.Settings["SourseUrl"].Value = this.txtWhereFloderUrl.Text.Trim();
                }
                else
                {
                    config.AppSettings.Settings.Add("SourseUrl", this.txtWhereFloderUrl.Text.Trim());
                }

                //2. 删除目标路径地址
                foreach (string key in myKeys)
                {
                    if (key.IndexOf("TargetUrl") >= 0)
                    {
                        //myTargetUrlList.Add(key);
                        config.AppSettings.Settings.Remove(key);
                    }
                }

                //3. 保存目标路径地址
                int tempLen = myUrlList.Count;
                for (int i = 0; i < tempLen; i++)
                {
                    config.AppSettings.Settings.Add(("TargetUrl" + (i + 1).ToString()), myUrlList[i]);
                }
                config.Save(ConfigurationSaveMode.Modified);
                ConfigurationManager.RefreshSection("appSettings");
                CommonForm.ShowMessage("保存配置成功！");
            }
            catch (Exception myEx)
            {
                CommonForm.ShowMessage(myEx.Message, 2);
            }
        }

        /// <summary>
        /// 设置ProgressBar的进度。
        /// </summary>
        /// <param name="pro"></param>
        /// <param name="proBar"></param>
        public void SetProgressBar(int pro)
        {
            //进度条显示
            this.processBar.Value = this.processBar.Value + pro;
            //百分比展示
            this.lblPersent.Text = (this.processBar.Value * 100 / processBar.Maximum).ToString() + "%";//显示百分比
            this.lblPersent.Update();
        }

        #region 确认复制多个，如果存在多个的话
        private void btnConfirmCopyAll_Click(object sender, EventArgs e)
        {
            if (!this.CheckInputV2())
            {
                return;
            }

            DataTable myDt = (DataTable)this.dgvUrl.DataSource;

            //配置进度条最大值
            int fileCount = FileMethod.GetFolderFileCount(this.txtWhereFloderUrl.Text);
            //根据复制的位置多少进行倍增
            this.processBar.Maximum = fileCount * myDt.Rows.Count;
            this.processBar.Value = 0;
            //传递代理
            FileMethod.DelegateProgressBar myProgressBar = new FileMethod.DelegateProgressBar(SetProgressBar);

            Thread objThread = new Thread(new ThreadStart(delegate
            {
                ThreadMethodTxt(this.txtWhereFloderUrl.Text, myDt, myProgressBar);
            }));
            objThread.Start();
        }
        #endregion

        //删除源文件
        private void btnDelSourseFolder_Click(object sender, EventArgs e)
        {
            if (!this.chkIsDelSourseFolder.Checked)
            {
                //如果未选中，直接返回
                return;
            }
            if (!string.IsNullOrWhiteSpace(this.txtWhereFloderUrl.Text))
            {
                //判断文件夹路径是否存在
                if (!Directory.Exists(this.txtWhereFloderUrl.Text))
                {
                    CommonForm.ShowMessage("文件夹路径不存在，请检查！", 1);
                    return;
                }

                //验证文件夹内是否存在具体文件
                string[] myFiles = Directory.GetFiles(".");
                if (myFiles.Length == 0)
                {
                    CommonForm.ShowMessage("文件夹为空，请检查！", 1);
                    return;
                }
            }
            else
            {
                CommonForm.ShowMessage("请选择文件路径！", 1);
                return;
            }


            DialogResult myResult = MessageBox.Show("是否确认删除源文件！", "提示", MessageBoxButtons.OKCancel);
            if (myResult == DialogResult.OK)
            {
                Directory.Delete(this.txtWhereFloderUrl.Text, true);
                CommonForm.ShowMessage("源文件删除成功！", 1);
            }
        }

        private void btnFileCount_Click(object sender, EventArgs e)
        {
            CommonForm.ShowMessage(FileMethod.GetFolderFileCount(this.txtWhereFloderUrl.Text).ToString());
        }

        //取消，返回上一层
        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        //关闭，关闭所有界面
        private void btnClose_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Abort;
        }

        private void FileCopy_Load(object sender, EventArgs e)
        {

        }
    }
}
